package com.system.oauthserver.config;

import com.system.oauthserver.service.imp.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.client.RestTemplate;

/**
 * spring security 配置
 * EnableGlobalMethodSecurity 下有4个注解可以使用
 * @PreAuthorize 在方法调用之前,基于表达式的计算结果来限制对方法的访问
 * @PostAuthorize 允许方法调用,但是如果表达式计算结果为false,将抛出一个安全性异常
 * @PostFilter 允许方法调用,但必须按照表达式来过滤方法的结果
 * @PreFilter 允许方法调用,但必须在进入方法之前过滤输入值
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled =true)//开启spring Security 注解
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Autowired
    MyRoleHierarchyImpl myRoleHierarchy;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    @Bean
    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return userDetailsService;
    }

    @Bean
    public RoleHierarchy roleHierarchy(){
        return myRoleHierarchy;
    }


    @Bean
    @ConditionalOnMissingBean({ClientHttpRequestFactory.class})
    public ClientHttpRequestFactory requestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        //ms
        factory.setConnectTimeout(15000);
        factory.setReadTimeout(15000);
        factory.setOutputStreaming(false);
        return factory;
    }

    @Bean
    @ConditionalOnMissingBean({RestTemplate.class})
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        //return builder.build();
        RestTemplate restTemplate = new RestTemplate(factory);
        return restTemplate;

    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 从数据库读取的用户进行身份认证
        auth.userDetailsService(userDetailsServiceBean())
                .passwordEncoder(passwordEncoder);
    }



}
